<!-- 动态输入框组件，用于表单的动态字段渲染。支持 string, number 和 object 三种类型（都支持单值和数组） -->
<template>
  <view class="dynamic-form">
    <!-- number / string 类型 -->
    <template v-if="form.type === 'number' || form.type === 'string'">
      <!-- 单值 -->
      <view v-if="!form.is_array" class="form-item">
        <text class="form-label">{{ form.name }}</text>
        <uni-easyinput class="form-input" v-model="form.value" :type="form.type === 'number' ? 'number' : 'text'"
          :placeholder="'请输入' + form.name" />
      </view>

      <!-- 多值 -->
      <view v-else class="form-item">
        <text class="form-label">{{ form.name }}</text>
        <view v-for="(item, index) in inputValues" :key="index" class="form-item with-delete">
          <uni-easyinput class="form-input" v-model="inputValues[index]"
            :type="form.type === 'number' ? 'number' : 'text'" :placeholder="'请输入' + form.name" />
          <button v-if="inputValues.length > 1" @click="removeInput(index)" type="warn" plain class="delete-btn">
            删除
          </button>
        </view>
        <button @click="addInput" type="primary" plain class="add-btn">增加一项</button>
      </view>
    </template>

    <!-- object 类型 -->
    <template v-else-if="form.type === 'object'">
      <view class="form-item">
        <text class="form-label">{{ form.name }}</text>

        <!-- 单值对象 -->
        <view v-if="!form.is_array" class="object-group">
          <view v-for="(opt, i) in form.options" :key="i" class="form-item">
            <uni-easyinput class="form-input" v-model="form.value[opt]" type="text" :placeholder="opt" />
          </view>
        </view>

        <!-- 数组对象 -->
        <view v-else>
          <view v-for="(obj, index) in objectValues" :key="index" class="object-item">
            <view v-for="(opt, i) in form.options" :key="i" class="form-item">
              <uni-easyinput class="form-input" v-model="objectValues[index][opt]" type="text" :placeholder="opt" />
            </view>
            <button v-if="objectValues.length > 1" @click="removeObject(index)" type="warn" plain class="delete-btn">
              删除
            </button>
          </view>
          <button @click="addObject" type="primary" plain class="add-btn">增加一项</button>
        </view>
      </view>
    </template>
  </view>
</template>

<script setup>
import { ref, watch } from "vue";

const props = defineProps({
  form: { type: Object, required: true },
});

const inputValues = ref(
  props.form.is_array && (props.form.type === "number" || props.form.type === "string")
    ? Array.isArray(props.form.value) ? [...props.form.value] : [""]
    : []
);

const objectValues = ref(
  props.form.is_array && props.form.type === "object"
    ? Array.isArray(props.form.value) ? [...props.form.value] : [{}]
    : []
);

// 同步回父级
watch(
  inputValues,
  (val) => {
    if (props.form.is_array && (props.form.type === "number" || props.form.type === "string")) {
      props.form.value = [...val];

      console.log("props.form.value:", props.form.value);
    }
  },
  { deep: true } // ✅ 深度监听，保证 push/splice/直接修改值都会触发
);

watch(
  objectValues,
  (val) => {
    if (props.form.is_array && props.form.type === "object") {
      // 这里最好用深拷贝，避免父组件和子组件的对象引用同一个内存
      props.form.value = val.map((obj) => ({ ...obj }));
      console.log("props.form.value:", props.form.value);
    }
  },
  { deep: true } // ✅ 深度监听对象属性
);

// methods
const addInput = () => inputValues.value.push("");
const removeInput = (index) => {
  if (inputValues.value.length > 1) inputValues.value.splice(index, 1);
};

const addObject = () => {
  const newObj = {};
  props.form.options.forEach((opt) => {
    newObj[opt] = "";
  });
  objectValues.value.push(newObj);
};
const removeObject = (index) => {
  if (objectValues.value.length > 1) objectValues.value.splice(index, 1);
};
</script>
<style scoped>
.form-item {
  margin-bottom: 30rpx;
}

.form-label {
  display: block;
  font-size: 28rpx;
  font-weight: 600;
  color: #333;
  margin-bottom: 16rpx;
}

.form-input {
  width: 100%;
  padding: 0 30rpx;
  box-sizing: border-box;
  font-size: 28rpx;
}

.with-delete {
  display: flex;
  align-items: center;
  margin-bottom: 16rpx;
}

.delete-btn {
  margin-left: 5rpx;
  font-size: 26rpx;
  border-radius: 8rpx;
}

.add-btn {
  margin-top: 20rpx;
  font-size: 26rpx;
}

.object-group {
  padding: 20rpx;
  border: 1px solid #e0e0e0;
  border-radius: 12rpx;
  background-color: #fafafa;
}

.object-item {
  margin-bottom: 20rpx;
  padding: 20rpx;
  border: 1px solid #e0e0e0;
  border-radius: 12rpx;
  background-color: #fff;
}
</style>

<!-- 父亲组件几个完整实例: -->
<!-- 1️⃣ 字符串类型单值form字段
{
  name: "颜色",
  type: "string",   // 字符串
  value: "红色",    // 单值,父亲组件传值可以没有这个字段，子组件会把动态输入框的值追加进去到这个字段给父亲组件，父亲可以不传这个，子组件会动态追加输入框的值进去
  options: ["红色", "蓝色", "绿色"], // 可选项
  is_array: false   // 单值
}


传给子组件：

<FormItem
  :form="form"
  :label="form.name"
  :type="form.type"
  :is_array="form.is_array"
  :options="form.options"
/>

2️⃣ 字符串类型数组form字段
{
  name: "颜色",
  type: "string",
  value: ["红色", "蓝色"], // 多值，父亲可以不传这个，子组件会动态追加输入框的值进去
  options: ["红色", "蓝色", "绿色"],
  is_array: true
}


传给子组件的方式同上。

3️⃣ 数字类型数组form字段
{
  name: "密度",
  type: "number",
  value: [1.2, 2.3], // 多值，父亲可以不传这个，子组件会动态追加输入框的值进去
  options: [],       // 数字一般不需要选项
  is_array: true
}

4️⃣ 对象类型数组form字段
{
  name: "体积",
  type: "object",
  value: [{ 长: 10, 宽: 5, 高: 2 }], // 多个对象，父亲可以不传这个，子组件会动态追加输入框的值进去
  options: ["长", "宽", "高"],        // 每个对象的字段
  is_array: true
}


✅ 总结：

form 对象是必须的，包含 name, type, value, options, is_array。

label 传 form.name，type 传 form.type，is_array 传 form.is_array，options 传 form.options || []。

子组件根据 type 和 is_array 自动渲染对应的单值、数组、对象输入框。 -->


<!-- 完整的使用实例：推荐参考下面的 -->
<!--  
//注意：value字段可传可不传，传则为输入框的默认值也就是回显，输入框值变化，会字段篡改父组件testForm的value字段值

<FormItem :form="testForm" :label="testForm.name" :type="testForm.type" :is_array="testForm.is_array"
      :options="testForm.options || []" />{{ testForm }}
      
//1.1字符串的单输入框
// const testForm = ref({
//   name: "颜色",
//   type: "string",  // 字符串
//   value: "红色",   // 单个值
//   is_array: false  // 单值
// })
//1.2字符串的多输入框
// const testForm = ref({
//   name: "颜色",
//   type: "string",  // 字符串 
//   value: ['红色的', '蓝色的'],//可以有输入框初始化值
//   is_array: true  // 多输入框
// })

//2.1数字类型的单输入框
// const testForm = ref({
//   name: "长度",
//   type: "number",  // 数字类型
//   value: 1.5,   // 单个值
//   is_array: false  // 单值
// })
//2.2数字类型的多输入框
// const testForm = ref({
//   name: "颜色",
//   type: "string",  // 数字类型 
//   value: [2.5, 101],//可以有输入框初始化值
//   is_array: true  // 多输入框
// })

//2.1数字类型的单输入框
// const testForm = ref({
//   name: "长度",
//   type: "number",  // 数字类型
//   value: 1.5,   // 单个值
//   is_array: false  // 单值
// })
//2.2数字类型的多输入框
// const testForm = ref({
//   name: "颜色",
//   type: "string",  // 数字类型 
//   value: [2.5, 101],//可以有输入框初始化值
//   is_array: true  // 多输入框
// })

//3.1对象类型的单输入框
// const testForm = ref({
//   name: "体积",
//   type: "object",  // 对象类型
//   value: { "长": 10, "宽": 5, "高": 2 },
//   options: ["长", "宽", "高"],// 每个对象的字段
//   is_array: false  // 单值
// })
//3.2对象类型的多输入框
// const testForm = ref({
//   name: "体积",
//   type: "object",  // 对象类型
//   value: [{ "长": 10, "宽": 5.5, "高": 2 }, { "长": 10.8, "宽": 5, "高": 2 }],
//   options: ["长", "宽", "高"],// 每个对象的字段
//   is_array: true  // 多值
// }) -->
